﻿using Kn.DLMS;
using Kn.DLMS.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using WindowsFormsApplication3;

namespace Kn.ALICE
{
    #region GXAliceCLD基类  信道状态信息
    public class GXAliceCLD
    {
        public string Name { get; set; }
        public ushort codeType { get; set; }
        public ushort dataLen { get; set; }

        public string strData { get; set; }

        public GXByteBuffer dataBuf = new GXByteBuffer();

        public string GetStatusMessage(StatusCode statusCode)
        {
            switch (statusCode)
            {
                case StatusCode.Connected:
                    return "已连接（※表示已入网）";
                case StatusCode.PINCodeError:
                    return "PIN码错误";
                case StatusCode.NoService:
                    return "无服务";
                case StatusCode.SIMCardDetectionFailed:
                    return "未获取身份信息（SIM卡检测失败）";
                case StatusCode.WrongUsernameOrPassword:
                    return "用户名/密码错误";
                case StatusCode.ConnectionRefused:
                    return "拒绝连接（PDP激活失败）";
                case StatusCode.ConnectionTimeout:
                    return "连接超时";
                case StatusCode.NetworkRegistrationFailed:
                    return "未获取到IP地址（网络注册失败）";
                case StatusCode.ConnectionDisconnected:
                    return "连接被远端断开";
                case StatusCode.NoSignal:
                    return "无信标";
                case StatusCode.NoHeartbeat:
                    return "无心跳";
                case StatusCode.OverCapacity:
                    return "超容限";
                case StatusCode.AddressConflict:
                    return "地址冲突";
                case StatusCode.PortOccupied:
                    return "端口占用";
                case StatusCode.ClientOffline:
                    return "客户端不在线(表示未入网)";
                case StatusCode.CacheFull:
                    return "缓存满";
                case StatusCode.UnknownError:
                    return "未知错误";
                default:
                    return "未定义状态";
            }
        }

        public virtual bool Parser()
        {
            // 可以在派生类中重写该方法
            return true;
        }

  
    }
    #endregion

    public class GXAliceCLD0001 : GXAliceCLD
    {
        public StatusCode cuChannelStatus;
        public GXAliceCLD0001()
        {
            Name = "CU信道工况";
            codeType = 0x0001;
            dataLen = 1;
        }

        public override bool Parser()
        {
            try
            {
                cuChannelStatus = (StatusCode)dataBuf.GetUInt8();

                dataBuf.Position = 0;
                strData = dataBuf.GetString(1) + " :数据 :" + ((byte)cuChannelStatus).ToString()+"-" + GetStatusMessage(cuChannelStatus) +"\r\n";
            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }
    }

    public class GXAliceCLD0002 : GXAliceCLD
    {
        byte SignalQuality;

        public byte LocalSignalQuality { get; set; } // 本端接收到的信号品质值
        public byte RemoteSignalQuality { get; set; } // 对端接收到的信号品质值


        public byte SNR;
        public double dSRN;

        public byte RSSI;
        public double dRSSI;

        public byte RSRP;
        public double dRSRP;


        public byte RSRQ;
        public double dRSRQ;

        public byte PowerReflectionRatio;
        public UInt16 SWR;


        public GXAliceCLD0002()
        {
            Name = "CU信号品质";
            codeType = 0x0002;
            dataLen = 1;
        }

        public override bool Parser()
        {
            try
            {
                SignalQuality = dataBuf.GetUInt8();


                SNR = dataBuf.GetUInt8();

                dSRN = SNR;
                if(dSRN != 0)
                {
                    dSRN = (dSRN * 0.5) - 31;
                }

                RSSI = dataBuf.GetUInt8();
                dRSSI = RSSI;
                if(dRSSI != 0)
                {
                    dRSSI -= 175;
                }

                RSRP = dataBuf.GetUInt8();
                dRSRP = RSRP;
                if (dRSRP != 0)
                {
                    dRSRP -= 157;
                }


                
                RSRQ = dataBuf.GetUInt8();
                dRSRQ = RSRQ;
                if (dRSRQ != 0)
                {
                    dRSRQ = (dRSRQ*0.5) - 20;
                }



                PowerReflectionRatio = dataBuf.GetUInt8();
                SWR = dataBuf.GetUInt16();

                dataBuf.Position = 0;
                strData = dataBuf.GetString(1) + "  :信号品质= " + SignalQuality.ToString()+ "\r\n";
                strData += dataBuf.GetString(1) + " :信噪比SRN =" + dSRN.ToString()+ "\r\n";
                strData += dataBuf.GetString(1) + " :接收信号强度指示RSSI =" + dRSSI.ToString()+ "\r\n";
                strData += dataBuf.GetString(1) + " :信号接收码功率RSRP =" + dRSRP.ToString()+ "db\r\n";
                strData += dataBuf.GetString(1) + " :信号接收码质量RSRQ  =" + dRSRQ.ToString() + "\r\n";
                strData += dataBuf.GetString(1) + " :功率反射比 =" + PowerReflectionRatio.ToString() + "未使用\r\n";
                strData += dataBuf.GetString(2) + " :驻波比SWR =" + SWR.ToString() +  "未使用\r\n";
            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }
    }

    public class GXAliceCLD0003 : GXAliceCLD
    {
        public NetworkEndpoint listen = new NetworkEndpoint();
        public GXAliceCLD0003()
        {
            Name = "SIM IP地址";
            codeType = 0x0003;
            dataLen = 1;
        }

        public override bool Parser()
        {
            try
            {
                dataBuf.Get(listen.ByteIpAddress);
                dataBuf.Get(listen.ByteIpAddressIPv6);
                dataBuf.Get(listen.BytePort);
                listen.Parser();

                dataBuf.Position = 0;
                strData = dataBuf.GetString(4) + "  :侦听服务IP地址/模块获取SIM的IPv4地址= " + listen.IpAddress + "\r\n";
                strData += dataBuf.GetString(16) + " :模块获取SIM的IPv6地址" + "\r\n";
                strData += dataBuf.GetString(2) + " :侦听服务端口=" + listen.Port.ToString() + "\r\n";


            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }
    }

    public class GXAliceCLD0004 : GXAliceCLD
    {
        public byte NetWorkProtocol;
        public string strNetWorkProtocol;

        public GXAliceCLD0004()
        {
            Name = "网络制式/协议";
            codeType = 0x0004;
            dataLen = 1;
        }

        public override bool Parser()
        {
            try
            {
                NetWorkProtocol = dataBuf.GetUInt8();

                if(NetWorkProtocol == 1)
                {
                    strNetWorkProtocol = "1-4G";
                }
                if (NetWorkProtocol == 2)
                {
                    strNetWorkProtocol = "2-3G";
                }
                if (NetWorkProtocol == 3)
                {
                    strNetWorkProtocol = "3-2G";
                }
                if (NetWorkProtocol == 4)
                {
                    strNetWorkProtocol = "4-catM";

                }
                if (NetWorkProtocol == 5)
                {
                    strNetWorkProtocol = "5-NB";
                }

                dataBuf.Position = 0;
                strData = dataBuf.GetString(1) + "当前网络制式:" + strNetWorkProtocol  + "\r\n";
            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }
    }

    public class GXAliceCLD0005 : GXAliceCLD
    {
        public StatusCode cuChannelStatus;
        public GXAliceCLD0005()
        {
            Name = "网络制式/协议";
            codeType = 0x0005;
            dataLen = 1;
        }

        public override bool Parser()
        {
            try
            {
                cuChannelStatus = (StatusCode)dataBuf.GetUInt8();

                dataBuf.Position = 0;
                strData = dataBuf.GetString(1) + " :数据 :" + ((byte)cuChannelStatus).ToString() + "-" + GetStatusMessage(cuChannelStatus) + "\r\n";
            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }
    }

    public class NetworkUnit
    {
        public int CurrentID { get; set; } // 当前网络单元ID



        public List<int> NeighborIDs { get; set; } // 邻域网络单元ID列表

        public int ConvertByteArrayToInt(byte[] bytes)
        {
            if (bytes.Length != 4)
            {
                throw new ArgumentException("字节数组的长度必须为4。");
            }

            //if (BitConverter.IsLittleEndian)
            //{
            //    Array.Reverse(bytes); // 如果系统是小端字节序，需要反转字节数组
            //}

            int value = BitConverter.ToInt32(bytes, 0);
            return value;
        }

        public NetworkUnit()
        {
            NeighborIDs = new List<int>();
        }


    }

    public class GXAliceCLD0006 : GXAliceCLD
    {

        public NetworkUnit networkUnit = new NetworkUnit();


        public GXAliceCLD0006()
        {
            Name = "CELL ID或CCO ID";
            codeType = 0x0006;
            dataLen = 1;
        }

        public override bool Parser()
        {
            try
            {
                byte[] tmp = new byte[4];

                dataBuf.Get(tmp);


                networkUnit.CurrentID = networkUnit.ConvertByteArrayToInt(tmp);

                int num = dataBuf.GetUInt8();
                for(int i = 0; i < num; i++)
                {
                    dataBuf.Get(tmp);
                    networkUnit.NeighborIDs.Add(networkUnit.ConvertByteArrayToInt(tmp));
                }

                dataBuf.Position = 0;
                strData = dataBuf.GetString(4) + " 当前网络单元ID:" + networkUnit.CurrentID.ToString() + "\r\n";
                strData += dataBuf.GetString(1) + " 邻域网络单元ID个数:" + networkUnit.NeighborIDs.Count.ToString() + "\r\n";
                
                for(int i = 0; i < num; i++)
                {
                    strData += dataBuf.GetString(4) + " 邻域网络单元ID" + (i+1).ToString()+":" + networkUnit.NeighborIDs[i].ToString() + "\r\n";
                }
            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }
    }

    public class GXAliceCLDUNKNOW : GXAliceCLD
    {
        public GXAliceCLDUNKNOW()
        {
            Name = "";
            codeType = 0xFFFF;
        }

        public override bool Parser()
        {
            try
            {
                strData = dataBuf.GetString(dataBuf.Size) + "  :数据\r\n";
            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }
    }

    public class GXAliceCLD_DICTIONARY
    {
        #region 原有方式
        //字段
        public Dictionary<ushort, GXAliceCLD> AliceCLDDictionary = new Dictionary<ushort, GXAliceCLD>(30);

        public GXAliceCLD_DICTIONARY()
        {
            GXAliceCLD CLD0001 = new GXAliceCLD0001();
            GXAliceCLD CLD0002 = new GXAliceCLD0002();
            GXAliceCLD CLD0003 = new GXAliceCLD0003();
            GXAliceCLD CLD0004 = new GXAliceCLD0004();
            GXAliceCLD CLD0005 = new GXAliceCLD0005();
            GXAliceCLD CLD0006 = new GXAliceCLD0006();

            GXAliceCLD CldUnknow = new GXAliceCLDUNKNOW();

            AliceCLDDictionary.Add(CLD0001.codeType, CLD0001);
            AliceCLDDictionary.Add(CLD0002.codeType, CLD0002);
            AliceCLDDictionary.Add(CLD0003.codeType, CLD0003);
            AliceCLDDictionary.Add(CLD0004.codeType, CLD0004);
            AliceCLDDictionary.Add(CLD0005.codeType, CLD0005);
            AliceCLDDictionary.Add(CLD0006.codeType, CLD0006);

            AliceCLDDictionary.Add(CldUnknow.codeType, CldUnknow);
        }
    }
}
#endregion